home *** CD-ROM | disk | FTP | other *** search
- ;============================
- ;Linkable module for PCX.PAS
- ;============================
-
- data segment word
-
- extrn datalength: word
- extrn scratch: dword
- extrn buff1: word, buff2: word
- extrn buff1seg, buff2seg: word
- extrn evenrow: byte
- extrn is_CGA: byte
- extrn page_addr: word
- extrn linestart: word
- extrn columncount: word
- extrn plane: word
- extrn repeatcount: byte
-
- writeproc dw (?)
-
- data ends
-
- code segment word public
- assume cs:code, ds:data
-
- public decode_pcx
-
- bytes_per_line equ 80
-
- ;===================== Store CGA image in buffer =========================
-
- STOREBYTE PROC near
-
- mov di, linestart ;get offset of col. 0
- add di, dx ;add column count
- cmp evenrow, 0 ;odd or even row?
- je row_odd
- add di, buff2 ;total offset in even buffer
- mov [es:di], bh ;put byte in even buffer
- jmp short add_col
- row_odd: add di, buff1 ;total offset in odd buffer
- mov [es:di], bh ;put byte in odd buffer
- add_col: inc dx ;increment column count
- cmp dx, bytes_per_line
- je row_ends ;end of a row
- ret ;not end of row, so finished
- row_ends: xor dx, dx ;reset column
- xor evenrow, 1 ;evenrow:= not evenrow
- cmp evenrow, 1 ;if row is even, start a new line
- je noteven
- mov es, buff1seg ;segment of even buffer
- add linestart, bytes_per_line ;new col. 0 offset
- ret
- noteven: mov es, buff2seg ;segment of even buffer
- ret
-
- STOREBYTE endp
-
- ;====================== Write EGA/VGA image to video =====================
-
- ;The data in the .PCX file is organized by color plane, by line; that is,
- ;all the data for plane 0 for line 1, then for plane 1, line 1, etc.
- ;Writing the data to display memory is just a matter of masking out the
- ;other planes while one plane is being written to. This is done with the
- ;map mask register in the sequencer. All the other weird and wonderful
- ;registers in the EGA/VGA do just fine with their default settings, thank
- ;goodness.
-
- WRITEBYTE proc near
-
- mov di, linestart ;offset of line beginning
- add di, dx ;add column
- mov [es:di], bh ;put byte in screen buffer
- inc dx
- cmp dx, bytes_per_line ;reached end of scanline?
- je doneline
- ret
- doneline: shl bp, 1 ;go to next plane
- cmp bp, 8 ;done last plane?
- jle setplane ;no
- mov bp, 1 ;yes, new line
- setplane: cli ;clear interrupts
- mov ax, bp ;plane is 1, 2, 4, or 8
- mov dx, 3C5h ;sequencer data register
- ;OK to wipe out DX since column counter is being zeroed anyway
- out dx, al ;mask out 3 planes
- sti ;enable interrupts
- xor dx, dx ;reset column count
- cmp bp, 1 ;if planes done,
- je new_line ; start new line
- ret
- new_line: add linestart, bytes_per_line ;new line
- ret
-
- WRITEBYTE endp
-
- ;=========================================================================
-
- DECODE_PCX PROC NEAR
-
- push bp
- cmp is_CGA, 1
- je CGAonly
- mov bp, plane ;store plane in bp
- mov ax, page_addr ;start of video buffer
- mov es, ax ;put in es for addressing
- mov writeproc, offset writebyte ;choose EGA/VGA procedure
- jmp short alltypes
- CGAonly: mov writeproc, offset storebyte ;choose CGA procedure
- mov es, buff1seg ;segment of odd buffer
- alltypes: mov bl, repeatcount ;count in bl
- mov si, word ptr 0 ;index into scratch
- mov dx, columncount ;column counter
- xor ch, ch ;clean up loop counter
- ;-------------------------------------------------------------------------
- ;Read buffer and decode data
-
- ;Here's how the data compression system works. Each byte is either image
- ;data or a count byte that tells how often the next image byte is repeated.
- ;The byte is image data if it follows a count byte, or if either of the top
- ;two bits is clear. Otherwise it is a count byte, with the count derived
- ;from the lower 6 bits.
-
- getbyte: cmp si, datalength ;end of scratch buffer?
- je exit ;yes, quit
- push es ;save video address
- les di, scratch ;put pointer in es:di
- add di, si ;add offset
- mov bh, [es:di] ;get byte from scratch
- inc si ;increment index
- pop es ;restore video address
- cmp bl, 0 ;was prev. byte a count?
- jg repeats ;yes, this is data
- mov ah, bh ;no, copy byte to ah
- and ah, 192 ; and test high bytes
- cmp ah, 192
- jne is_data ;not set, not a count
- ;--------------------------------------------------------------------------
- ;It's a count byte
- xor bh, 192 ;get count from 6 low bits
- mov bl, bh ;store repeat count
- jmp short getbyte ;go get data byte
- ;----------------------------------------------------------------------------
- ;It's a single data byte; call CGA or EGA routine once
- is_data: call writeproc
- jmp getbyte
- ;---------------------------------------------------------------------------
- ;It's data to be written "count" times; call CGA or EGA routine repeatedly
- repeats: mov cl, bl ;set loop counter
- go: call writeproc
- loop go ;write byte cx times
- mov bl, 0 ;clear count byte
- jmp getbyte
- ;-------------------------------------------------------------------------
- exit: mov plane, bp ;save status for next
- mov repeatcount, bl ; run thru buffer
- mov columncount, dx
- pop bp
- ret
-
- DECODE_PCX endp
-
- ;=========================================================================
- code ends
- end
-